package com.xj.openapi4j.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson2.JSON;
import com.xj.dao.DispatchListDto;
import com.xj.dao.DispatchListsNumDto;
import com.xj.dao.DispatchlistsDto;
import com.xj.dao.InventoryDao;
import com.xj.openapi4j.service.token.U8Token;
import com.xj.openapi4j.service.token.YsToken;
import com.xj.openapi4j.util.HttpUtil;
import com.xj.openapi4j.util.RequestTool;
import com.xj.server.serviceInterface.TransfersSaleOrderInterface;
import com.xj.util.Constance;
import com.xj.util.DateUtils;
import com.xj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * Copyright(c) 2015-2015 by yonyouup. All Rights Reserved 销售订单
 *
 * @author yanwuyang
 * @version <类版本> , 2015年12月8日
 * @see <相关类/方法>
 * @since <产品/模块版本>
 */
@SuppressWarnings("all")
@Slf4j
@Service
@EnableScheduling
public class TransfersSaleOrderService  implements TransfersSaleOrderInterface {
    @Value("${u8AppKey}")
    String u8AppKey;

    @Value("${u8AppSecret}")
    String u8AppSecret;
    @Value("${fromAccount}")
    String from_account;
    @Autowired
    U8Token u8Token;
    @Autowired
    YsToken ysToken;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    CustomerService customerService;
    @Autowired
    PersonService personService;
    @Autowired
    NoteService noteService;
    @Autowired
    InventoryDao inventoryDao;
    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
   // @Transactional(rollbackOn = Exception.class)
    public String transSaleorder(String saleOrderode) throws Exception {
        String auditor = "";
        try {
            if (StringUtils.isEmpty(saleOrderode)) {
                log.info("同步YS销售订单的订单号为空!");
                return "同步YS销售订单的订单号为空!";
            }
            JSONArray data = getYsorder(saleOrderode);
            if (saleOrderode.startsWith("XXX")) {
                return "XXX";
            }
            if (CollectionUtils.isEmpty(data)) {
                log.info("YS未查询到此销售订单,订单编号：{}", saleOrderode);
                return "YS系统未查询到此销售订单" + saleOrderode;
            }
            if (saleOrderode.startsWith("YDD")) {
                //检查U8中是否存在此订单，若存在，则报告错误并返回
                JSONObject row=data.getJSONObject(0);
                 List<Map<String, String>> saleorderList = inventoryDao.checkSaleorder(saleOrderode);
                if (!CollectionUtils.isEmpty(saleorderList)) {
                    Map<String, String> saleorderMap = saleorderList.get(0);
                    Date ysmodifyTime = data.getJSONObject(0).getDate("modifyTime");
                    if (ysmodifyTime == null) {
                        redisTemplate.opsForSet().remove(Constance.ysSaleorder, saleOrderode);
                        return "订单已同步且未发生修改,不需要再次同步!";
                    }
                     boolean issuccess=delOrder(saleOrderode);
                     if(issuccess){
                        auditor = trans2U8saleOrder(data, saleOrderode);
                     }
                } else {
                    auditor = trans2U8saleOrder(data, saleOrderode);
                }

            } else if (saleOrderode.startsWith("XXD")) {
                //检查U8中是否存在此订单，若存在，则报告错误并返回
                List<Map<String, String>> dispatchList = inventoryDao.checkDispatch(saleOrderode);
                if (dispatchList.size() > 1) {
                    log.info("订单:{}在U8发货单中有多条", saleOrderode);
                    throw new Exception("订单:" + saleOrderode + "在U8发货单中有多条");
                }
                if (!CollectionUtils.isEmpty(dispatchList)) {
                    Map<String, String> dispatchMap = dispatchList.get(0);

                    String cverifier = dispatchMap.get("cverifier") == null ? "" : dispatchMap.get("cverifier").toString();
                    if (StringUtils.isNotEmpty(cverifier)) {
                        log.info("U8发货单已同步此销售订单号,单号：{}", saleOrderode);
                        String title = "销售订单同步失败";
                        String content = "U8发货单已存在并审核订单:" + saleOrderode + ",请先在U8删除弃审发货单，再进行同步!";
                        String cmaker = dispatchList.get(0).get("cmaker");
                        String yhtUserid = noteService.getYhtUsridByname(cmaker);
                        noteService.sendMessage(title, content, yhtUserid);
                        redisTemplate.boundSetOps(Constance.ysSaleorder).remove(saleOrderode);
                        return "U8中已存在此销售订单" + saleOrderode;
                    } else {
                        Date ysmodifyTime = data.getJSONObject(0).getDate("modifyTime");
                        Date pubuts = data.getJSONObject(0).getDate("pubuts");
                        //未发生修改，不需要再次同部
                        if (ysmodifyTime == null) {
                            redisTemplate.opsForSet().remove(Constance.ysSaleorder, saleOrderode);
                            return "订单已同步且未发生修改,不需要再次同步!";
                        }
                        String dlid = dispatchMap.get("dlid").toString();
                            List<Map<String, Object>> u8DetailList = inventoryDao.getDetailBymainid(dlid);
                            TypeReference<List<DispatchListsNumDto>> typeReference = new TypeReference<List<DispatchListsNumDto>>() {
                            };

                            List<DispatchListsNumDto> dispatchListsNumDtoList = JSONObject.parseObject(JSON.toJSONString(u8DetailList), typeReference);
                            //检查销售订单中的存货编码、数量与金额是否发生变化
                            boolean ischange = checkOrderDetailChange(data, dispatchListsNumDtoList);
                            if (ischange) {
                                //先删除发货单，再重新增加
                                delDispatch(saleOrderode);
                                CompletableFuture<String> completableFuture=CompletableFuture.supplyAsync(()-> {
                                    try {
                                        String auditor1 = trans2U8dispatch(data, saleOrderode);
                                        return auditor1;
                                    }catch (Exception err){
                                        log.error("trans2U8dispatch err:{}",err);
                                        throw  new RuntimeException(err);
                                    }
                                },threadPoolTaskExecutor);
                                auditor=completableFuture.get(3,TimeUnit.MINUTES);
                                return  auditor;
                            } else {
                                //更新表头和表体数据
                                JSONObject yshead = data.getJSONObject(0);
                                String remark = yshead.getString("purchaseNo");
                                //课题号
                                String cdefine11 = yshead.getString("orderDefineCharacter__d101");
                                String receiver = yshead.getString("receiver");
                                String receiveMobile = yshead.getString("receiveMobile");
                                String cshipaddress = yshead.getString("receiveAddress");
                                DispatchListDto dispatchListDto = new DispatchListDto(dlid, cshipaddress, receiver, cdefine11, receiver, receiveMobile, remark, new Date());
                                this.inventoryDao.updateDispatch(dispatchListDto);
                                for (int i = 0; i < data.size(); i++) {
                                    JSONObject detail = data.getJSONObject(i);
                                    String cinvcode = detail.getString("productCode");
                                    String prodname = detail.getString("productName");
                                    BigDecimal taxunitprice = detail.getBigDecimal("oriTaxUnitPrice");

                                    BigDecimal taxrate = detail.getBigDecimal("taxRate");
                                    JSONObject orderDetailPrices = detail.getJSONObject("orderDetailPrices");
                                    BigDecimal  iquotedprice=detail.getBigDecimal("prodPrice");
                                  //  BigDecimal iunitprice = orderDetailPrices.getBigDecimal("oriUnitPrice");
                                    BigDecimal iunitprice = detail.getBigDecimal("oriTaxUnitPrice").divide(new BigDecimal(1+detail.getDoubleValue("taxRate")/100),6,BigDecimal.ROUND_HALF_UP);
                                    BigDecimal discount1=new BigDecimal(100);
                                    if(detail.getDoubleValue("prodPrice")>0d){
                                        discount1=detail.getBigDecimal("oriTaxUnitPrice").multiply(new BigDecimal(100)).divide(detail.getBigDecimal("prodPrice"),4,BigDecimal.ROUND_HALF_UP);
                                    }

                                    BigDecimal imoney = orderDetailPrices.getBigDecimal("oriMoney");
                                    BigDecimal itax = orderDetailPrices.getBigDecimal("oriTax");
                                    BigDecimal isum = detail.getBigDecimal("oriSum");
                                    String cmemo = detail.getString("lineMemo");
                                    Integer rowno = detail.getIntValue("lineno")/10;
                                    DispatchlistsDto dispatchlistsDto = new DispatchlistsDto(dlid, rowno, cinvcode, prodname, iquotedprice, iunitprice, taxunitprice, imoney, itax, isum, iunitprice, imoney, itax, isum, cmemo,discount1);
                                    this.inventoryDao.updateDispatchs(dispatchlistsDto);
                                }
                            }

                    }
                } else {
                    CompletableFuture<String> completableFuture=CompletableFuture.supplyAsync(()-> {
                        try {
                            String auditor1 = trans2U8dispatch(data, saleOrderode);
                            return auditor1;
                        }catch (Exception err){
                            err.printStackTrace();
                            throw  new RuntimeException(err);
                        }
                    },threadPoolTaskExecutor);
                    auditor=completableFuture.get(3,TimeUnit.MINUTES);
                    return  auditor;
                }
            } else {
                log.info("同步YS销售订单的订单号不符合要求!");
                return "同步YS销售订单的订单号不符合要求!";
            }

            redisTemplate.boundSetOps(Constance.ysSaleorder).remove(saleOrderode);
            String str = "YS系统订单:" + saleOrderode + "同步到U8" + (saleOrderode.startsWith("YDD") ? "订单" : "发货单") + "完成!";
            Set<String> errorOrderSet = redisTemplate.boundSetOps(Constance.errorOrder).members();
            errorOrderSet.remove(saleOrderode);
            return str;
        } catch (Throwable err) {
            err.printStackTrace();
            log.info("同步订单{}失败，原因为{}", saleOrderode, err);
            //向审核人员发送消息
            String title = "YS系统订单:" + saleOrderode + "同步到U8" + (saleOrderode.startsWith("YDD") ? "订单" : "发货单") + "失败!";
            String content = "订单" + saleOrderode + "同步失败，原因" + err.getMessage();
            String yhtUsrid = noteService.getYhtUsridByname(auditor);
            noteService.sendMessage(title, content, yhtUsrid);
            redisTemplate.opsForSet().add(Constance.errorOrder, saleOrderode);
            redisTemplate.opsForSet().remove(Constance.ysSaleorder, saleOrderode);
            return content;
        }
    }

    @Override
    public String autoTransSaleOrder() throws Exception {
        log.info("开如同步YS系统销售订单");
        Set<String> sets = redisTemplate.boundSetOps(Constance.ysSaleorder).members();
        Set backsets = new HashSet(sets);
        Iterator<String> its = backsets.iterator();
        while (its.hasNext()) {
            String saleorder = its.next();
            redisTemplate.boundSetOps(Constance.ysSaleorder).remove(saleorder);
            if (saleorder == null) {
                continue;
            }
            //检单是否有错误，如有错误，将销售订单保存到redis中
            Set<String> errorOrder = redisTemplate.boundSetOps(Constance.errorOrder).members();
            if (errorOrder.contains(saleorder)) {
                continue;
            }
           String result=  transSaleorder(saleorder);
            if("XXX".equals(result)){
                sets = redisTemplate.boundSetOps(Constance.ysSaleorder).members();
                backsets = new HashSet(sets);
                its = backsets.iterator();
            }
        }
        return "同部数据完成";
    }

    private JSONArray getYsorder(String code) throws Exception {
        String token = ysToken.getToken();
        String requestUrl = "https://c3.yonyoucloud.com/iuap-api-auth/yonbip//sd/voucherorder/list?access_token=" + token;
        JSONObject map = new JSONObject();
        map.put("pageIndex", 1);
        map.put("pageSize", "200");
        if (code.startsWith("XXX")) {
            String str = code.replace("XXX", "");
            Date vouchtime = DateUtils.parseDate(str, "yyyy-MM-dd HH:mm:ss");
            Date beginDate = DateUtils.addMinutes(vouchtime, -1);
            Date endDate = DateUtils.addMinutes(vouchtime, 1);
            map.put("open_orderDate_begin", DateUtils.formatDate(beginDate, "yyyy-MM-dd HH:mm:ss"));
            map.put("open_orderDate_end", DateUtils.formatDate(endDate, "yyyy-MM-dd HH:mm:ss"));
        } else {
            map.put("code", code);
        }

        String str = HttpUtil.post(requestUrl, map.toJSONString());
      //  log.info(str);
        JSONObject jsonObject = JSONObject.parseObject(str);
        if (jsonObject.getIntValue("code") == 200) {
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray jsonArray = data.getJSONArray("recordList");
            if (code.startsWith("XXX")) {
                Set<String> orderSet = new HashSet<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject row = jsonArray.getJSONObject(i);
                    String ordercode = row.getString("code");
                    orderSet.add(ordercode);
                }
                for (String orderno : orderSet) {
                    redisTemplate.opsForSet().add(Constance.ysSaleorder, orderno);
                }
                redisTemplate.opsForSet().remove(Constance.ysSaleorder, code);
            }
            return jsonArray;
        }
        return null;
    }


    //返回YS订单审核人
    private String trans2U8saleOrder(JSONArray jsonArray, String salecode) throws Exception {
        String defaultAuditor = "刘阳";
        JSONObject head = new JSONObject();
        JSONArray detail = new JSONArray();
        String u8url = "https://api.yonyouup.com/api/saleorder/add";
        Map<String, String> paramMap = new HashMap();
        paramMap.put("from_account", from_account);
        paramMap.put("to_account", from_account);
        paramMap.put("app_key", u8AppKey);
        paramMap.put("token", u8Token.getToken());
        paramMap.put("sync", "1");
        paramMap.put("tradeid", getTradeid(salecode));
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject data = jsonArray.getJSONObject(i);
            head.put("deptcode", "01");
            head.put("code", salecode);
            if (StringUtils.isEmpty(data.getString("auditor")) ) {
                return "预定单" + salecode + "审核后才能传送数据";
            }

            String linecloser = data.getString("linecloser");
            String statusCode = data.getString("statusCode");
            if ("OPPOSE".equals(statusCode)) {
                throw new Exception("订单已抛单,同步取消");
            }
            if (StringUtils.isNotEmpty(linecloser)) {
                continue;
            }
            //交易唯一识别号，防止重复提交
            //   String biz_id = data.getString("bizId");
            //    paramMap.put("biz_id", biz_id);
            if (data.getDate("auditTime") == null) {
                head.put("date", DateUtils.formatDate(data.getDate("createTime"), "yyyy-MM-dd"));
            } else {
                head.put("date", DateUtils.formatDate(data.getDate("auditTime"), "yyyy-MM-dd"));
            }
            //  head.put("date", "2024-03-01");
            head.put("businesstype", "普通销售");
            String bizFlow_name = data.getString("bizFlow_name");
            if (salecode.startsWith("YDD")) {
                head.put("typecode", "YD");
            } else {
                head.put("typecode", "XX");
            }
            head.put("state", "Opening");
            String custId_name = data.getString("agentId_name");
            JSONObject customerInfo = customerService.getCustominfo(custId_name, null);
            if (customerInfo == null || StringUtils.isEmpty(customerInfo.getString("code"))) {
                throw new Exception("获取客户编码为空");
            }
            head.put("custcode", customerInfo.getString("code"));
            head.put("cusname", custId_name);
            //表头备注
            String remark = data.getString("purchaseNo");
            head.put("memo", remark);
            //课题号
            String orderDefineCharacter__d101 = data.getString("orderDefineCharacter__d101");
            head.put("define11", orderDefineCharacter__d101);
            String auditor = data.getString("auditor");
            if (StringUtils.isNotEmpty(auditor)) {
                defaultAuditor = auditor;
                JSONObject personInfo = personService.getPersonInfo(auditor);
                if (personInfo == null || StringUtils.isEmpty(customerInfo.getString("code"))) {
                    throw new Exception("获取人员编码为空");
                }
                head.put("personcode", personInfo.getString("code"));
            } else {
                //如果单据没有审核，则业务员设置为刘阳
                head.put("personcode", "070");
            }
            String receiver = data.getString("receiver");
            String receiveMobile = data.getString("receiveMobile");

            String receiveAddress = data.getString("receiveAddress");
            head.put("sendaddress", receiveAddress);
            head.put("ccusperson", receiver);
            head.put("maker", auditor);
            JSONObject body = new JSONObject();
            body.put("inventorycode", data.getString("productCode"));
        //    body.put("inventoryName", data.getString("productName"));
            body.put("invstd", data.getString("specDescription"));
            //仓库为标准库
            //  body.put("warehouse_code","bzp");
            body.put("unitcode", data.getString("purUOM_Code"));
            body.put("quantity", data.getDoubleValue("qty"));

            body.put("taxrate", data.getDoubleValue("taxRate"));

            JSONObject orderDetailPrices = data.getJSONObject("orderDetailPrices");
            body.put("money", orderDetailPrices.getDoubleValue("oriMoney"));

            body.put("taxunitprice", orderDetailPrices.getDoubleValue("natTaxUnitPrice"));
            BigDecimal  unitprice=new BigDecimal(orderDetailPrices.getDoubleValue("natTaxUnitPrice")).divide(
                    new BigDecimal(1+data.getDoubleValue("taxRate")/100),6,BigDecimal.ROUND_HALF_UP);

           // body.put("quotedprice",orderDetailPrices.getDoubleValue("salePrice_domestic"));
            body.put("quotedprice",data.getDoubleValue("prodPrice"));
            if(data.getDoubleValue("prodPrice")==0){
                body.put("discountrate",100);

            }else {
                BigDecimal discount1=orderDetailPrices.getBigDecimal("natTaxUnitPrice").multiply(new BigDecimal(100)).divide(data.getBigDecimal("prodPrice"),4,BigDecimal.ROUND_HALF_UP);
                body.put("discountrate",discount1.floatValue());
            }
            //   body.put("natunitprice",orderDetailPrices.getDoubleValue("natUnitPrice"));
           // body.put("unitprice",orderDetailPrices.getDoubleValue("oriUnitPrice"));
            body.put("unitprice",unitprice.doubleValue());


            //行备注  api文档无此字段
            String lineMemo = data.getString("lineMemo");
            body.put("memo", lineMemo);
            body.put("tax", orderDetailPrices.getDoubleValue("oriTax"));
            body.put("sum", data.getDoubleValue("oriSum"));
            body.put("rowno", data.getIntValue("lineno")/10);
            detail.add(body);
        }
        if (detail.size() == 0) {
            throw new Exception("表体数据已全部进行关闭,无可用数据同步！");
        }
        head.put("entry", detail);
        JSONObject saleorder = new JSONObject();
        saleorder.put("saleorder", head);
        String url = RequestTool.getUrl(u8url, paramMap);
        String responseStr = HttpUtil.post(url, saleorder.toJSONString());
        log.info(responseStr);
        return defaultAuditor;
    }

    //返回YS订单审核人
    private String trans2U8dispatch(JSONArray jsonArray, String salecode) throws Exception {
        String defaultAuditor = "刘阳";
        JSONObject head = new JSONObject();
        JSONArray detail = new JSONArray();
        String u8url = "https://api.yonyouup.com/api/consignment/add";
        Map<String, String> paramMap = new HashMap();
        paramMap.put("from_account", from_account);
        paramMap.put("to_account", from_account);
        paramMap.put("sync", "1");
        paramMap.put("app_key", u8AppKey);
        paramMap.put("token", u8Token.getToken());
        paramMap.put("tradeid", getTradeid(salecode));
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject data = jsonArray.getJSONObject(i);
            head.put("deptcode", "01");
            head.put("code", salecode);
            String linecloser = data.getString("linecloser");
            String statusCode = data.getString("statusCode");
            if ("OPPOSE".equals(statusCode)) {
                throw new Exception("订单已抛单,同步取消");
            }
            if (StringUtils.isNotEmpty(linecloser)) {
                continue;
            }
            //交易唯一识别号，防止重复提交
            //   String biz_id=data.getString("bizId");
            //   paramMap.put("biz_id",biz_id);
            if (data.getDate("auditTime") == null) {
                head.put("date", DateUtils.formatDate(data.getDate("createTime"), "yyyy-MM-dd"));
            } else {
                head.put("date", DateUtils.formatDate(data.getDate("auditTime"), "yyyy-MM-dd"));
            }
            //  head.put("date","2024-03-01");
            head.put("operation_type", "普通销售");
            String bizFlow_name = data.getString("bizFlow_name");
            if (salecode.startsWith("XXD")) {
                head.put("saletype", "XX");
            } else {
                head.put("saletype", "YD");
            }
            head.put("state", "Opening");
            String custId_name = data.getString("agentId_name");
            JSONObject customerInfo = customerService.getCustominfo(custId_name, null);
            if (customerInfo == null || StringUtils.isEmpty(customerInfo.getString("code"))) {
                throw new Exception("获取客户编码为空");
            }
            head.put("custcode", customerInfo.getString("code"));
            head.put("cusname", custId_name);
            //表头备注
            String remark = data.getString("purchaseNo");
            head.put("remark", remark);
            //课题号
            String orderDefineCharacter__d101 = data.getString("orderDefineCharacter__d101");
            head.put("define11", orderDefineCharacter__d101);
            String auditor = data.getString("auditor");
            if (StringUtils.isNotEmpty(auditor)) {
                defaultAuditor = auditor;
                JSONObject personInfo = personService.getPersonInfo(auditor);
                if (personInfo == null || StringUtils.isEmpty(customerInfo.getString("code"))) {
                    throw new Exception("获取人员编码为空");
                }
                head.put("personcode", personInfo.getString("code"));
            } else {
                //没有审核，业务员为demo
                head.put("personcode", "070");
            }
            String receiver = data.getString("receiver");
            String receiveMobile = data.getString("receiveMobile");
            head.put("ccontactname", receiver);
            head.put("ccusperson", receiver);
            String receiveAddress = data.getString("receiveAddress");
            head.put("cdeliveradd", receiveAddress);
            head.put("mobilephone", receiveMobile);
            if(StringUtils.isNotEmpty(auditor)){
                head.put("maker", auditor);
            }else {
                head.put("maker", "demo");
            }
            JSONObject body = new JSONObject();
            body.put("inventory_code", data.getString("productCode"));
            body.put("inventory_name", data.getString("productName"));
            body.put("invstd", data.getString("specDescription"));
            //仓库为标准库
            body.put("warehouse_code", "bzp");
            body.put("ccomunitcode", data.getString("purUOM_Code"));
            body.put("quantity", data.getDoubleValue("qty"));
            body.put("taxprice", data.getDoubleValue("oriTaxUnitPrice"));
            body.put("taxrate", data.getDoubleValue("taxRate"));
            JSONObject orderDetailPrices = data.getJSONObject("orderDetailPrices");
            body.put("money", orderDetailPrices.getDoubleValue("oriMoney"));
            BigDecimal price=new BigDecimal(data.getDoubleValue("oriTaxUnitPrice")).divide(
                    new BigDecimal(1+ data.getDoubleValue("taxRate")/100),6,BigDecimal.ROUND_HALF_UP);
            body.put("natprice",price.doubleValue());
            //   body.put("quotedprice",orderDetailPrices.getDoubleValue("salePrice_domestic"));
            body.put("quotedprice",data.getDoubleValue("prodPrice"));
             if(data.getDoubleValue("prodPrice")==0){
                 body.put("discount1",100);
             }else {
                 BigDecimal discount1=data.getBigDecimal("oriTaxUnitPrice").multiply(new BigDecimal(100)).divide(data.getBigDecimal("prodPrice"),4,BigDecimal.ROUND_HALF_UP);
                 body.put("discount1",discount1.floatValue());
             }

            body.put("price",price.doubleValue());

          //    body.put("natprice",orderDetailPrices.getDoubleValue("natUnitPrice"));
          //    body.put("price",orderDetailPrices.getDoubleValue("oriUnitPrice"));

            //行备注  api文档无此字段
            String lineMemo = data.getString("lineMemo");
            body.put("remark", lineMemo);
            body.put("tax", orderDetailPrices.getDoubleValue("oriTax"));
            body.put("sum", data.getDoubleValue("oriSum"));
            body.put("rowno", data.getIntValue("lineno")/10);
            detail.add(body);
        }

        if (detail.size() == 0) {
            throw new Exception("表体数据已全部进行关闭,无可用数据同步！");
        }
        head.put("entry", detail);
        JSONObject consignment = new JSONObject();
        consignment.put("consignment", head);
        String url = RequestTool.getUrl(u8url, paramMap);
        String responseStr = HttpUtil.post(url, consignment.toJSONString());
        log.info(responseStr);
        return defaultAuditor;
    }


    //获取交易号，防止重复提交
    private String getTradeid(String saleOrdercode) throws Exception {
        //在U8中检查是否存在此订单号，若不存在，在redis删除saleorder与tradeid对应关系，重新生成，否则则直接取数
        if (saleOrdercode.startsWith("YDD")) {
            List list = inventoryDao.checkSaleorder(saleOrdercode);
            if (list.size() == 0) {
                redisTemplate.opsForHash().delete(Constance.tradeid, saleOrdercode);
            }
        } else if (saleOrdercode.startsWith("XXD")) {
            List list = inventoryDao.checkDispatch(saleOrdercode);
            if (list.size() == 0) {
                redisTemplate.opsForHash().delete(Constance.tradeid, saleOrdercode);
            }
        }
        String tradeid = (String) redisTemplate.opsForHash().get(Constance.tradeid, saleOrdercode);
        if (StringUtils.isNotEmpty(tradeid)) {
            return tradeid;
        }
        String url = "https://api.yonyouup.com/system/tradeid";
        Map<String, String> paramMap = new HashMap();
        paramMap.put("from_account", from_account);
        paramMap.put("app_key", u8AppKey);
        paramMap.put("token", u8Token.getToken());
        String str = RequestTool.doGet(url, paramMap);
        JSONObject jsonObject = JSONObject.parseObject(str);
        if ("0".equals(jsonObject.getString("errcode"))) {
            String id = jsonObject.getJSONObject("trade").getString("id");
            redisTemplate.opsForHash().put(Constance.tradeid, saleOrdercode, id);
            redisTemplate.expire(Constance.tradeid, 30, TimeUnit.DAYS);
            return id;
        }
        return null;
    }


    private boolean checkOrderDetailChange(JSONArray data, List<DispatchListsNumDto> u8DetailList) {
        List<DispatchListsNumDto> u8list = new ArrayList<>(u8DetailList);
        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i);
            String cinvcode = jsonObject.getString("productCode");
            BigDecimal quantity = jsonObject.getBigDecimal("qty");
            Integer rowno = jsonObject.getIntValue("lineno")/10;
            DispatchListsNumDto dispatchListsNumDto = new DispatchListsNumDto(cinvcode, quantity, rowno);
            if (u8list.contains(dispatchListsNumDto)) {
                u8list.remove(dispatchListsNumDto);
            } else {
                return true;
            }
        }
        if (u8list.size() == 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public void  autoDelCancelAuditOrder() throws Exception {
        log.info("开如删除YS系统取消审核的销售订单");
        Set<String> sets = redisTemplate.boundSetOps(Constance.cancelAuditOrder).members();
        Set backsets = new HashSet(sets);
        Iterator<String> its = backsets.iterator();
        while (its.hasNext()) {
            String saleorder = its.next();
            //从redis中删除
            redisTemplate.boundSetOps(Constance.cancelAuditOrder).remove(saleorder);
            if (saleorder == null) {
                continue;
            }
            //从errorOrder中删除ordercode
            redisTemplate.boundSetOps(Constance.errorOrder).remove(saleorder);
            boolean issuccess=  delOrder(saleorder);
           log.info("删除订单{}，是否成功={}",saleorder,issuccess);
        }
    }


    private boolean delOrder(String saleorder) throws Exception {
        List<Map<String, String>> saleorderList = inventoryDao.checkSaleorder(saleorder);
        if (!CollectionUtils.isEmpty(saleorderList)) {
            Map<String, String> saleorderMap = saleorderList.get(0);
            String cverifier = saleorderMap.get("cverifier") == null ? "" : saleorderMap.get("cverifier").toString();
            if (StringUtils.isNotEmpty(cverifier)) {
                log.info("U8已审核此销售订单,单号：{}", saleorder);
                String title = "销售订单已审核！";
                String content = "U8销售订单已审核此订单:" + saleorder + ",请在U8中弃审销售订单!";
                String cmaker = saleorderList.get(0).get("cmaker");
                String yhtUserid = noteService.getYhtUsridByname(cmaker);
                noteService.sendMessage(title, content, yhtUserid);
                return false;
            } else {
                String id = saleorderMap.get("id").toString();
                int i = inventoryDao.deleteOrderDetailByid(id);
                if (i > 0) {
                    i = inventoryDao.deleteOrderMainByid(id);
                }
            }
        }
        return true;
    }

    public void autoDelDispatchlist() throws Exception {
        log.info("开如同步YS系统销售订单");
        Set<String> sets = redisTemplate.boundSetOps(Constance.delOrRejectOrder).members();
        Set backsets = new HashSet(sets);
        Iterator<String> its = backsets.iterator();
        while (its.hasNext()) {
            String saleorder = its.next();
            if (saleorder == null) {
                redisTemplate.boundSetOps(Constance.delOrRejectOrder).remove(saleorder);
                continue;
            }
            if(saleorder.startsWith("XXD")){
                //从redis中删除
                redisTemplate.boundSetOps(Constance.delOrRejectOrder).remove(saleorder);
                //从errorOrder中删除ordercode
                redisTemplate.boundSetOps(Constance.errorOrder).remove(saleorder);
                delDispatch(saleorder);
            }
        }
    }

    @Override
    public void autoDelSaleorder() throws Exception {
        log.info("开如同步YS系统销售订单");
        Set<String> sets = redisTemplate.boundSetOps(Constance.delOrRejectOrder).members();
        Set backsets = new HashSet(sets);
        Iterator<String> its = backsets.iterator();
        while (its.hasNext()) {
            String saleorder = its.next();
            if (saleorder == null) {
                redisTemplate.boundSetOps(Constance.delOrRejectOrder).remove(saleorder);
                continue;
            }
            if(saleorder.startsWith("YDD")){
                //从redis中删除
                redisTemplate.boundSetOps(Constance.delOrRejectOrder).remove(saleorder);
                //从errorOrder中删除ordercode
                redisTemplate.boundSetOps(Constance.errorOrder).remove(saleorder);
                delOrder(saleorder);
            }

        }
    }
    public String delDispatch(String saleOrderode) throws Exception {
            List<Map<String, String>> dispatchList = inventoryDao.checkDispatch(saleOrderode);
        if (dispatchList.size() > 1) {
            log.info("订单:{}在U8发货单中有多条", saleOrderode);
            throw new Exception("订单:" + saleOrderode + "在U8发货单中有多条");
        }
        if (!CollectionUtils.isEmpty(dispatchList)) {
            Map<String, String> dispatchMap = dispatchList.get(0);
            String cverifier = dispatchMap.get("cverifier") == null ? "" : dispatchMap.get("cverifier").toString();
            if (StringUtils.isNotEmpty(cverifier)) {
                log.info("U8发货单已同步此销售订单号,单号：{}", saleOrderode);
                String title = "销售订单同步失败";
                String content = "U8发货单已存在并审核订单:" + saleOrderode + ",请先在U8删除弃审发货单，再进行同步!";
                String cmaker = dispatchList.get(0).get("cmaker");
                String yhtUserid = noteService.getYhtUsridByname(cmaker);
                noteService.sendMessage(title, content, yhtUserid);
                BoundSetOperations<String, String> sets = redisTemplate.boundSetOps(Constance.ysSaleorder);
                redisTemplate.boundSetOps(Constance.ysSaleorder).remove(saleOrderode);
                return "U8中已存在此销售订单" + saleOrderode;
            }else {
                String dlid = dispatchMap.get("dlid").toString();
                List<Map<String, Object>> u8DetailList = inventoryDao.getDetailBymainid(dlid);
                int i = inventoryDao.deleteDispatchListsBydlid(dlid);
                if (i > 0) {
                    i = inventoryDao.deleteDispatchListBydlid(dlid);
                }
                //更新现存量
                updateCurrentStock(u8DetailList);
            }
        }
        return "预订单" + saleOrderode + "删除成功!";
    }

    public void   updateCurrentStock( List<Map<String, Object>> u8DetailList){
        for(Map<String,Object> map:u8DetailList){
            String cinvcode=map.get("cinvcode")==null?"":map.get("cinvcode").toString();
            //减少预计出库
            BigDecimal iquantity=new BigDecimal(map.get("iquantity")==null?"0":map.get("iquantity").toString()).negate();
           List<Map<String,Integer>>  stockRecords=this.inventoryDao.getCurrentStockBycinvcode("bzp",cinvcode);
           if(stockRecords.size()>0){
               Integer autoid=stockRecords.get(0).get("autoid");
             this.inventoryDao.updateCurrentStock(autoid,iquantity);
           }else {
               Integer  itemdid=this.inventoryDao.getItemid()+1;
               this.inventoryDao.insertCurrentstock(cinvcode,iquantity,itemdid);
           }

        }
    }
}